﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Deployment.BuildManager.ExternalProcess.Common;
using System.IO;
using Microsoft.Build.BuildEngine;


namespace Deployment.BuildManager.ExternalProcess.CreatePackage
{
    public class BuildTask : IBuildTask
    {
        #region IBuildTask Members

        public SetupInfo Execute(SetupInfo info)
        {
            //Configura produto/branch/versão no arquivo resources.xml.
            this.SetResourcesAtributes(info);

            //Adiciona os arquivos de resources no xml.
            this.AddAssembliesToResource(info);

            // Inclui os arquivos de resources no csproj.
            this.UpdateSetupCsProj(info);

            return null;
        }

        public void Cancel()
        {
            throw new NotImplementedException();
        }

        #endregion

        #region Private Methods
        
        private string FormatResourcePath(string path)
        {
            return path.Replace(@"\", ".").Replace("-", "_").Replace("Æ", "ã").Replace("‚", "é").Replace("¢", "ó").Replace("‡", "ç").Replace(" ", "_");
        }

        #endregion

        #region Internal Methods

        internal void AddAssembliesToResource(SetupInfo info)
        {
            this.SendMessage("Configurando o Resource do Projeto de Template...");
            string xmlPath = info.SetupTemplateProjectPath + Path.DirectorySeparatorChar + BuildConstants.ResourceFolder + Path.DirectorySeparatorChar + BuildConstants.ResourceXml;

            XDocument resourceXml = XDocument.Load(xmlPath);

            foreach (ResourceItem item in info.CompiledFiles)
            {
                XElement resourceItem = new XElement("Resource",
                                        new XAttribute("name", FormatResourcePath(item.CompiledFullPath) + item.Name),
                                        new XAttribute("extractPath", BuildConstants.SetupBinFolder + Path.DirectorySeparatorChar + item.CompiledFullPath + item.Name));

                resourceXml.Element("Resources").Add(resourceItem);
            }

            resourceXml.Save(xmlPath);
        }

        /// <summary>
        /// Configura os atributos do elemento Resources do arquivo resources.xml
        /// </summary>
        /// <param name="info"></param>
        internal void SetResourcesAtributes(SetupInfo info)
        {
            string xmlPath = info.SetupTemplateProjectPath + Path.DirectorySeparatorChar + BuildConstants.ResourceFolder + Path.DirectorySeparatorChar + BuildConstants.ResourceXml;

            XDocument resourceXml = XDocument.Load(xmlPath);

            //Todo: Alterar
            resourceXml.Element("Resources").Attribute("System").Value = info.ProductName;
            resourceXml.Element("Resources").Attribute("Type").Value = info.BranchType.ToString();
            resourceXml.Element("Resources").Attribute("Version").Value = info.Version.Major.ToString();

            resourceXml.Save(xmlPath);
        }

        /// <summary>
        /// Inclui os arquivos de resources no csproj.
        /// </summary>
        /// <param name="info"></param>
        internal void UpdateSetupCsProj(SetupInfo info)
        {
            this.SendMessage("Atualizando Projeto de Template...");
            string csProjPath = info.SetupTemplateProjectPath + Path.DirectorySeparatorChar + BuildConstants.SetupTemplateCsProjName;

            XDocument csProjXml = XDocument.Load(csProjPath);

            XNamespace xmlns = "http://schemas.microsoft.com/developer/msbuild/2003";

            csProjXml.Element(xmlns + "Project")
                        .Element(xmlns + "PropertyGroup")
                        .Element(xmlns + "AssemblyName").Value = info.ProductName + "_"
                                                                + info.ModuleName + "_"
                                                                + "v" + info.Version + "_x86";

            foreach (ResourceItem item in info.CompiledFiles)
            {
                XElement ItemGroup = new XElement(xmlns + "ItemGroup",
                                        new XElement(xmlns + "EmbeddedResource",
                                        new XAttribute("Include", BuildConstants.ResourceFolder +
                                                                    Path.DirectorySeparatorChar +
                                                                    item.CompiledFullPath + item.Name)));

                csProjXml.Element(xmlns + "Project").Add(ItemGroup);
            }

            csProjXml.Save(csProjPath);
        }

        #endregion

        #region [ Events ]

        public event EventHandler<MessageEventArgs> MessageReceived;

        private void SendMessage(string message)
        {
            if (MessageReceived != null)
            {
                MessageEventArgs eventArgs = new MessageEventArgs(message);
                Logger.Log(message, Logger.EntryType.Information);
                MessageReceived(this, eventArgs);
            }
        }

        #endregion [ Events ]
    }
}
